package com.itheima.reggie.controller;

import com.github.pagehelper.PageInfo;
import com.itheima.reggie.entity.Employee;
import com.itheima.reggie.entity.MyPage;
import com.itheima.reggie.entity.R;
import com.itheima.reggie.service.EmployeeService;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController/*@RestController注解 = @Controller注解 + @ResponseBody注解
@Controller  表示该类被SpringMVC管理,可以接收http请求,返回响应数据
@ResponseBody  表示要返回的是字符串,如果返回值类型是对象或者集合,会自动将对象和集合转成JSON字符串再返回*/
@RequestMapping("/employee")//注意类路径前面有"/"否则Tomcat跑不起来
@Slf4j
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    @PostMapping("/login")
    public R login(@RequestBody Employee employee, HttpServletRequest httpServletRequest) {//@RequestBody表示数据来自于请求体中,是JSON字符串

        log.info("开始登录操作...");

        //1.密码使用MD5加密,等会将要与数据库表中已经加密的密码数据进行比较
        //digest [ˈdaɪdʒest/] v.消化,领悟,理解 n.摘要,概要
        String password = employee.getPassword();
        String encryptedPassword = DigestUtils.md5DigestAsHex(password.getBytes());
        employee.setPassword(encryptedPassword);

        //2.根据用户名查询数据库,返回查询到Employee对象
        Employee resultEmployee = employeeService.selectByUsername(employee);

        //3.判断叫该用户名的用户是否存在
        if (resultEmployee == null) {
            return R.error("对不起,您输入的用户名不存在...");
        }

        //4.用户存在,则判断密码是否正确(加密密码与加密密码比较)
        if (!employee.getPassword().equals(resultEmployee.getPassword())) {
            return R.error("对不起,您输入的密码不正确...");
        }

        //5.用户存在,且密码正确,则判断是否是禁用状态
        if (resultEmployee.getStatus() == 0) {
            return R.error("对不起,该账号处于禁用状态,请联系数据库管理员!");
        }

        //6.登陆成功
        HttpSession session = httpServletRequest.getSession();
        session.setAttribute("isLogin", resultEmployee.getId());

        /**生成JWT令牌*/
        JwtBuilder jwtBuilder = Jwts.builder(); //获得JWT令牌构造器
        Map<String, Object> map = new HashMap<>();
        map.put("CurrentLoginUserId", resultEmployee.getId());
        //。。。。。

        String token = jwtBuilder.setSubject("userLogin") //设置主题
                .setIssuedAt(new Date()) //设置jwt生成时间
                .setId("1") //设置id为token id
                .setClaims(map) //载荷部分用户自定义的信息
                .setExpiration(new Date(System.currentTimeMillis() + 1800000)) //设置token有效期 30min
                .signWith(SignatureAlgorithm.HS256, "itcast") //设置token加密方式和密钥
                .compact(); //生成token字符串
        System.err.println("生成token:"+token);
        //生成token:eyJhbGciOiJIUzI1NiJ9.eyJDdXJyZW50TG9naW5Vc2VySWQiOjEsImV4cCI6MTY4MzYzNjc5NH0.8xjJLTEW99M9yCVgvkeBKHQHHJmNCqnFpABNE3xy7pw

        resultEmployee.setPassword(token);//密码本就不需要穿给前端,用password的位置放令牌

        return R.success(resultEmployee);
    }

    @PostMapping("/logout")
    public R logout(HttpServletRequest httpServletRequest) {

        HttpSession session = httpServletRequest.getSession();
        session.removeAttribute("isLogin");//清除session中指定的键值对,表示结束登录状态

        //应该在前端js中删除浏览器Cookie缓存中的token令牌

        return R.success("退出成功");
    }

    @PostMapping
    public R save(@RequestBody Employee employee, HttpServletRequest request) {//@RequestBody表示数据来自于请求体中,是JSON字符串

        //准备缺失字段
        //密码,初始密码123456,需要进行md5加密处理
        employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
        //创建时间和最后修改时间
        employee.setCreateTime(LocalDateTime.now());
        employee.setUpdateTime(LocalDateTime.now());
        //获取当前登录人的信息
        Long isLogin = (Long) request.getSession().getAttribute("isLogin");
        // `create_user` bigint(20) NOT NULL COMMENT '创建人'
        // `update_user` bigint(20) NOT NULL COMMENT '修改人',
        // 创建人修改人就是数值类型的,直接把session中拿到的登录人的id存进去即可
        employee.setCreateUser(isLogin);
        employee.setUpdateUser(isLogin);

        log.info("待插入的employee内容为:" + employee);

        //调用service层存储新增的员工信息
        employeeService.save(employee);
        return R.success("新增员工成功");
    }


    @GetMapping("/page")
    public R selectByPage(int page, int pageSize, String name) {
        PageInfo<Employee> pageInfo = employeeService.selectByPage(page, pageSize, name);
        MyPage<Employee> myPage = new MyPage<>();
        myPage.setTotal(pageInfo.getTotal());
        myPage.setRecords(pageInfo.getList());
        return R.success(myPage);
    }

    @PutMapping
    public R update(@RequestBody Employee employee, HttpServletRequest request) {

        //生成updateTime
        employee.setUpdateTime(LocalDateTime.now());
        //生成updateUser
        Long isLogin = (Long) request.getSession().getAttribute("isLogin");
        employee.setUpdateUser(isLogin);

        employeeService.update(employee);//根据id修改 status username name phone sex id_number updateTime updateUser
        return R.success("修改状态成功");
    }


    @GetMapping("/{id}")
    public R selectAllById(@PathVariable Integer id) {
        Employee employee = employeeService.selectAllById(id);
        return R.success(employee);
    }

}
